package transfer;

import core.Util;

public class FileFragment {

	public static final byte NAME_FRG = 0;
	public static final byte DATA_FRG = 1;
	public static final byte HASH_FRG = 2;
	public static final byte MISC_FRG = 3;

	private byte[] fragment;
	
	public FileFragment(){
		
	}
	public FileFragment(String frag){
		this( Util.getBytes(frag) );
	}
	public FileFragment(byte[] frag){
		fragment = frag;
	}
	
	/**
	 * Returns the type of fragment
	 * @return
	 * @throws NoFragmentException
	 */
	public byte getType(){
		byte ret = -1;
			switch(fragment[0]){
				case 'n':
					ret = NAME_FRG;
					break;
				case 'm':
					ret = MISC_FRG;
					break;
				case 'h':
					ret = HASH_FRG;
					break;
				default:
					ret = DATA_FRG;
					break;
			}
		return ret;
	}
	
	public int getTotalPieces(){
		int ret = 0;
		ret = Integer.parseInt(Util.getString(fragment).substring(Util.indexOf(fragment,'/')+1,Util.indexOf(fragment,':')));
		return ret;
	}
	
	public int getPiece(){
		int ret = -1;
			byte t = getType();
			if(t != DATA_FRG){
				ret = -t;
			}else{
				ret = Integer.parseInt(Util.getString(subArray(0,Util.indexOf(fragment,'/'))));
			}
		return ret;
	}
	
	public String getHash(){
		String ret = "";
		int i = Util.lastIndexOf(fragment,'@');
		if(i > 0 ){//there is a hash, because there is an @
			ret = Util.getString(subArray(i+1,fragment.length));
		}
		return ret;
	}

	public byte[] getData(){
		int i = Util.lastIndexOf(fragment,'@');
		if( i < 0){
			i=fragment.length;
		}
		return subArray(Util.indexOf(fragment,':')+1, i);
	}
	
	public int getDataLen(){
		int i = Util.lastIndexOf(fragment,'@');
		if( i < 0){
			i=fragment.length;
		}
		return i-Util.indexOf(fragment,':')-1;
	}
	
	public String toString(){
		return Util.getString(fragment);
	}

	public byte[] subArray(int start, int end){
		byte[] ret = new byte[end-start];
		for(int i=0; i<ret.length; i++){
			ret[i] = fragment[i+start];
		}
		return ret;
	}

	public String subString(int start, int end){
		String ret = "";
		for(int i=start; i<end; i++){
			ret += (char)fragment[i];
		}
		return ret;
	}
	
	
	/**
	 * 
	 * @param data the data in the fragment
	 * @param type the fragment type, 0,1,2,3
	 * @param piece the piece #, use 0-x
	 * @param total the total # of pieces
	 * @return returns a fragment, with hash computed
	 */
	public static FileFragment buildFragment(byte[] data, byte type, int piece, int total){
		String p1 = "";
		String p2 = "";
		switch(type){
		case NAME_FRG:
			p1="n";
			p2 = "@"+FileTransfer.getHash(data);
			break;
		default:
		case DATA_FRG:
			p1=""+piece;
			p2 = "@"+FileTransfer.getHash(data);
			break;
		case HASH_FRG:
			p1="h";
			break;
		case MISC_FRG:
			p1="m";
			break;
		}
		byte[] pas = Util.combine(Util.getBytes(p1+"/"+total+":"),Util.combine(data,Util.getBytes(p2)));
		FileFragment f = new FileFragment(pas);
		return f;
	}
	public static FileFragment buildFragment(String data, byte type, int piece, int total){
		return buildFragment(Util.getBytes(data),type,piece,total);
	}
	
	
	
}
